//题目:
//给你2个矩阵A、B，我们使用标准的矩阵相乘定义C = AB如下：  A数组中栏（column）的数目一定要等于B数组中列（row）的数目才可以做此2数组的相乘。
//若我们以rows(A)，columns(A)分 别代表A数组中列及栏的数目，要计算C数组共需要的乘法的数目为：rows(A) * columns(B) * columns(A)。
//例如：A数组是一个 10x20的矩阵，B数组是个20x15的矩阵，那么要算出C数组需要做10 * 15 * 20，也就是3000次乘法。 
//要计算超过2个以上的矩阵相乘就得决定要用怎样的顺序来做。例如：X、Y、Z都是矩阵，要计算XYZ的话可以有2种选择：(XY)Z 或者 X(YZ)。
// 
//假设X是5x10的数组，Y是10x20的数组，Z是20x35的数组，那个不同的运算顺序所需的乘法数会有不同：(XY)Z • 5 * 20 * 10 = 1000次乘法完成(XY)，
//并得到一5x20的数组。 • 5 * 35 * 20 = 3500次乘法得到最后的结果。 总共需要的乘法的次数：1000 + 3500 = 4500。 

//X(YZ) • 10 * 35 * 20 = 7000次乘法完成(YZ)，并得到一10x35的数组。 
//• 5 * 35 * 10 = 1750次乘法得到最后的结果。 • 总共需要的乘法的次数：7000 + 1750 = 8750。 
// 
//很明显的，我们可以知道计算(XY)Z会使用较少次的乘法。 
//这个问题是：给你一些矩阵，你要写一个程序来决定该如何相乘的顺序，使得用到乘法的次数会最少。
//输入：含有多组测试数据，每组测试数据的第一列，含有1个整数N（N <= 10）代表有多少个数组要相乘。
//接下来有N对整数，代表一数组的列数及栏数。这N个数组的顺序与要你相乘的数组顺序是一样的。N = 0代表输入结束。请参考Sample Input。
//输出：每组测试数据输出一列，内容为矩阵相乘的顺序（以刮号来表示）使得所用的乘法次数最小。如果有不只一组答案，输出任一组均可。请参考Sample Output。
//样例输入：
//3
//1 5
//5 20
//20 1      100+20  100+5
//3
//5 10
//10 20
//20 35     4500
//6
//30 35
//35 15
//15 5
//5 10
//10 20
//20 25
//0
//样例输出：
//Case 1: (A1 x(A2 x A3))
//Case 2 : ((A1 x A2) x A3)
//Case 3 : ((A1 x(A2 x A3)) x((A4 x A5) x A6))
#include<iostream>
#include<limits.h>
#include<vector>

using namespace std;


int min_value=INT_MAX;
string ret;

void dfs(const vector<vector<int>>& nums,const vector<string>& v_str,int sum)
{
    if (nums.size() == 1) {
        if (sum < min_value)
            min_value = sum, ret = v_str[0];
        return;
    }
    vector<vector<int>> vv(nums.begin(),nums.end());
    vector<string> v_str_buf(v_str.begin(), v_str.end());

    for (int i = 1; i < nums.size(); i++)
    {
        if (nums[i-1][1]==nums[i][0])//矩阵相乘的前提条件：A的列数 = B的行数
        {
            //让每个nums[i]都与它前一个元素相乘
            int count = nums[i - 1][0] * nums[i - 1][1] * nums[i][1];//相乘所需的次数

            vv.insert(vv.begin() + i + 1, vector<int>{ nums[i - 1][0], nums[i][1] });//插入新生成的矩阵
            string str = "(" + v_str_buf[i - 1] + "*" + v_str_buf[i] + ")";
            v_str_buf.insert(v_str_buf.begin() + i + 1, str);

            vv.erase(vv.begin() + i),vv.erase(vv.begin() + i - 1);//删除两个已经相乘过的矩阵
            v_str_buf.erase(v_str_buf.begin() + i), v_str_buf.erase(v_str_buf.begin() + i - 1);

            dfs(vv, v_str_buf,sum + count);

            vv = nums, v_str_buf = v_str;//回溯
        }
    }
}

void get_min_count(const vector<vector<int>>& nums)
{ 
    string str;
    vector<string> v_str(nums.size());
    //初始化v_str
    for (int i = 1; i <= nums.size(); i++)
        v_str[i - 1] = "A" + to_string(i);
    dfs(nums,v_str,0);
    
}

int main()
{
    int n;
    cin >> n;
    while (n != 0)
    {
        //1.输入n组数据
        vector<vector<int>> vv(n,vector<int>(2));
        for (int i = 0; i < n; i++)
            cin >> vv[i][0] >> vv[i][1];
        //2.计算n个矩阵中最少相乘次数的顺序
        get_min_count(vv);

        //cout << min_value << ":";
        cout << ret << endl;
        min_value = INT_MAX, ret = "";
        cin >> n;
    }
    return 0;
}